package br.edu.ufabc.lnc.peanho.fuzzylogic;

import java.util.List;

import br.edu.ufabc.lnc.peanho.view.Sprite;

import jess.Context;
import jess.JessException;
import nrc.fuzzy.FuzzyValue;
import nrc.fuzzy.FuzzyVariable;
import nrc.fuzzy.TriangleFuzzySet;
import nrc.fuzzy.XValueOutsideUODException;
import nrc.fuzzy.XValuesOutOfOrderException;
import nrc.fuzzy.jess.FuzzyRete;

public class InferenceEngine {

	private FuzzyRete engine;
	private Context context;
	private FuzzyVariable fuzzyVariable;

	public InferenceEngine() {
		this.engine = new FuzzyRete();
		this.context = engine.getGlobalContext();
		try {
			engine
					.batch("br/edu/ufabc/lnc/peanho/fuzzylogic/FuzzyInferenceSystem.clp");
			engine.reset();
			engine.run(1);
			fuzzyVariable = (FuzzyVariable) engine.fetch("FUZZYVARIABLE")
					.javaObjectValue(context);
		} catch (JessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void configure(List<Sprite> interestPoints) {
		try {
			for (Sprite sprite : interestPoints) {
				int[] readings = sprite.getReadings();
				for (int i = 0; i < readings.length; i++) {
					try {
						FuzzyValue fuzzyValue = new FuzzyValue(fuzzyVariable,
								new TriangleFuzzySet(readings[i], 0.5));
						engine.store("RECEIVEDSIGNALSTRENGTH", fuzzyValue);
						engine.store("CELLID", sprite.getId());
						engine.store("APID", i);
						engine
								.eval("(assert (rss (fetch APID) (fetch CELLID) (fetch RECEIVEDSIGNALSTRENGTH)))");
					} catch (XValueOutsideUODException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (XValuesOutOfOrderException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			engine.run();
		} catch (JessException jessException) {
			jessException.printStackTrace();
		}
	}

	public String computeNearestInterestPoint(int[] readings) {
		String spriteId = null;
		try {
			engine.setFocus("SIMILARITY");
			for (int i = 0; i < readings.length; i++) {
				try {
					FuzzyValue fuzzyValue = new FuzzyValue(fuzzyVariable,
							new TriangleFuzzySet(readings[i], 0.5));
					engine.store("APID", i);
					engine.store("RECEIVEDSIGNALSTRENGTH", fuzzyValue);
					engine
							.eval("(assert (user-input (fetch APID) (fetch RECEIVEDSIGNALSTRENGTH)))");
					engine.run();
					spriteId = (String) engine.fetch("INTERESTCELL")
							.javaObjectValue(context);

				} catch (XValueOutsideUODException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (XValuesOutOfOrderException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (JessException jessException) {
			// TODO Auto-generated catch block
			jessException.printStackTrace();
		}
		return spriteId;
	}
}
